// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

/*
 * @Author: qiulin_JXGM ql1746365080@gmail.com
 * @Date: 2024-10-11 15:36:29
 * @LastEditors: qiulin 1746365080@qq.com
 * @LastEditTime: 2025-01-02 17:13:24
 * @FilePath: \SGFEM\Import\BDFImport\BulkData\Constraint\RBE1Parser.cpp
 */
#include "Import/BDFImport/BulkData/Constraint/RBE1Parser.h"

#include <algorithm>
#include <iostream>

#include <boost/algorithm/string.hpp>

#include "Utility/Logging/SGLogger.h"

#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Constraint/IRBE1Service.h"

#include "Import/BDFImport/BDFParserBase.h"

BULKDATA_ENTRY_PARSER_REG (RBE1);

using namespace SG::DBManager;
using namespace SG::Import;
using namespace SG::Import::BDF;
using namespace SG::DataStructure;
/*
// file://./../../Doc/MarkDown/BulkData/RBE1/RBE1.md>
*/
SG::DataStructure::Common::Status BDF::BULKDATA::ParseRBE1 (const std::shared_ptr<SG::DBManager::DBServiceFactory>& dbServiceFactory,
                                                            std::vector<std::string>&                               dividedEntryInfo)
{
    SG::DataStructure::FEM::RBE1Data tempData;

    // TODO(bug 001) m_dominId的正确填写
    tempData.m_domainId = 1;
    // 解析字符串

    // 解析 ID
    tempData.m_id = convertToI64 (dividedEntryInfo[1]);

    size_t const rowCount = dividedEntryInfo.size () / 10;  // 该词条共有多少行
    // 寻找UM所在行
    size_t umRow = 0;
    for (size_t i = 0; i < rowCount; i++)
    {
        std::string umStr = dividedEntryInfo[i * 10 + 1];
        boost::trim (umStr);
        if ("UM" == umStr)
        {
            umRow = i;
            break;
        }
    }

    // 插入GM
    for (size_t curRow = 0; curRow < umRow; curRow++)
    {
        for (size_t fieldsColumn = 2; fieldsColumn < 8; fieldsColumn += 2)
        {
            // 计算当前字段的索引
            const size_t curIndex  = curRow * 10 + fieldsColumn;
            std::string& curStrKey = dividedEntryInfo[curIndex];
            bool const   isEmpty   = is_all_space (curStrKey);
            if (isEmpty)
            {
                break;
            }

            SG::DataStructure::Common::Id const gm = convertToI64 (curStrKey);
            SG::DataStructure::Common::Id const cm = convertToI64 (dividedEntryInfo[curIndex + 1]);
            tempData.m_depList.push_back ({ gm, cm });
        }
    }

    // 获取最后一个非空下标
    size_t const rowNum      = dividedEntryInfo.size () / 10;
    size_t       judgeRownum = rowNum - 1;
    int          lastindex   = findNonEmptyIndex (dividedEntryInfo, judgeRownum);  // 词条最后一个非空下标
    while (-1 == lastindex)
    {
        judgeRownum--;
        if (judgeRownum < 0)
        {
            throw std::runtime_error ("RBE2Parser: judgeRownum < 0");
        }
        lastindex = findNonEmptyIndex (dividedEntryInfo, judgeRownum);
    }
    size_t lastUmIndex = lastindex + 1;  // GM与CM结尾的下一个下标
    if (lastindex != -1)
    {
        // 获取最后两个非空元素
        std::string rfirstNonEmpty  = dividedEntryInfo[lastindex];
        std::string rsecondNonEmpty = dividedEntryInfo[lastindex - 1];

        // 存在两个浮点数则为alpha，Tref
        if (rsecondNonEmpty.find ('.') == std::string::npos)
        {
            tempData.m_refTemperature = convertToReal (rfirstNonEmpty);
            tempData.m_alpha          = convertToReal (rsecondNonEmpty);
            lastUmIndex               = lastindex - 1;
        }
        else
        {
            // 存在一个浮点数为alpha
            if (rfirstNonEmpty.find ('.') == std::string::npos)
            {
                tempData.m_alpha = convertToReal (rfirstNonEmpty);
                lastUmIndex      = lastindex;
            }
        }
    }

    // 插入m_GN
    for (size_t curRow = umRow; curRow < rowCount; curRow++)
    {
        for (size_t fieldsColumn = 2; fieldsColumn < 8; fieldsColumn += 2)
        {
            size_t const curIndex = curRow * 10 + fieldsColumn;
            if (curIndex == lastUmIndex)  // 说明此时的下标代表的字符串已经不是GM了
            {
                break;
            }
            std::string& curStrKey = dividedEntryInfo[curIndex];
            bool const   isEmpty   = is_all_space (curStrKey);
            if (isEmpty)
            {
                break;
            }

            SG::DataStructure::Common::Id const gn = convertToI64 (dividedEntryInfo[curIndex]);
            SG::DataStructure::Common::Id const cn = convertToI64 (dividedEntryInfo[curIndex + 1]);
            tempData.m_indepList.push_back ({ gn, cn });
        }
    }

    return dbServiceFactory->get<IRBE1Service> ()->Add (tempData);
}
